package org.ediba.siri.core.action.data;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.ediba.siri.core.Filter;
import org.ediba.siri.core.action.data.ActionRequestDao;
import org.ediba.siri.core.action.domain.ActionRequest;
import org.ediba.siri.core.common.data.HibernateDomainDao;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.sql.JoinFragment;

public class HibernateActionRequestDao extends HibernateDomainDao<ActionRequest, Integer> implements ActionRequestDao {
	
	public HibernateActionRequestDao(){super(ActionRequest.class);}

	@Override
	protected DetachedCriteria buildCriteria(Map<Filter,Collection<Object>> filters){
		DetachedCriteria detachedCriteria = this.buildCriteria();
		Disjunction or;
		Conjunction and = Restrictions.conjunction();
		
		for (Map.Entry<Filter,Collection<Object>> filter : filters.entrySet()){
			or = Restrictions.disjunction();			
			for (Object value : filter.getValue()) 
				switch (filter.getKey()) {
				case USER: or.add(Restrictions.eq(Filter.USER.getPropertyId(), value));
					break;
				case IMAGE:
				case PUBLICATION:
					DetachedCriteria dc1 = detachedCriteria.createCriteria("image", JoinFragment.INNER_JOIN);
					DetachedCriteria dc2 = dc1.createCriteria("request", JoinFragment.INNER_JOIN);
					if (value == null)
						dc2.add(Restrictions.isNull(filter.getKey().getProperty()));
					else {
						@SuppressWarnings("unchecked")
						Collection<Integer> _collection = (Collection<Integer>)value;
						dc2.add(Restrictions.in(filter.getKey().getPropertyId(), _collection));
					}
				break;
				case ACTIONGRANT:
					if (value==null)
						or.add(Restrictions.isNull(Filter.ACTIONGRANT.getProperty()));
				break;
				case ACTIONREJECT:
					if (value==null)
						or.add(Restrictions.isNull(Filter.ACTIONREJECT.getProperty()));
				break;
				}
			and.add(or);
		}
			
		detachedCriteria.add(and);
		
		return detachedCriteria;
	}
	
	@Override
	protected DetachedCriteria buildCriteria(Collection<Map<Filter,Object>> filters){
		DetachedCriteria detachedCriteria = this.buildCriteria();
		Disjunction or = Restrictions.disjunction();
		Conjunction and;
		
		for (Map<Filter, Object> filter : filters) {
			and = Restrictions.conjunction();
			for (Map.Entry<Filter,Object> entry: filter.entrySet())
				switch (entry.getKey()) {
				case USER:
				case IMAGE:
				case PUBLICATION:	if (entry.getValue() == null)
										and.add(Restrictions.isNull(entry.getKey().getProperty()));
									else 
										and.add(Restrictions.eq(entry.getKey().getPropertyId(), entry.getValue()));
				}
			or.add(and);
		}
		detachedCriteria.add(or);
		
		return detachedCriteria;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ActionRequest> findOpen(Integer idImage, Integer idUser, Integer idPublication){
		String _hql = "";
		
		_hql += "from org.ediba.siri.core.action.domain.ActionRequest ar where";
		_hql += "     ar.actionreject is empty";
		_hql += " and ar.actiongrant is empty";
		_hql += " and ar.actionfinish is empty";
		if (idImage != null)
		_hql += " and ar.image.id = " + idImage.toString();
		if (idUser != null)
		_hql += " and ar.user.id = " + idUser.toString();
		if (idPublication != null)
		_hql += " and ar.publication.id = " + idPublication.toString();
		
		return (List<ActionRequest>) this.getHibernateTemplate().find(_hql);
	}
}